/**
 * test-client.js - 测试客户端
 * 用于连接到热键检测服务器并接收热键信息
 */
const net = require('net');

// 配置
const SERVER_HOST = 'localhost';
const SERVER_PORT = 11111;
const APP_NAME = 'app2'; // 应用名称

// 接收缓冲区，处理消息边界问题
let dataBuffer = '';

/**
 * 连接到热键检测服务器
 */
function connectToHotKeyServer() {
  console.log(`正在连接到热键检测服务器 ${SERVER_HOST}:${SERVER_PORT}...`);
  
  // 创建客户端socket
  const client = net.createConnection({
    host: SERVER_HOST,
    port: SERVER_PORT
  });
  
  // 设置编码
  client.setEncoding('utf8');
  
  // 连接成功事件
  client.on('connect', () => {
    console.log('连接成功！');
    
    // 发送注册消息
    registerApp(client, APP_NAME);
  });
  
  // 接收数据事件
  client.on('data', (data) => {
    try {
      // 将新数据添加到缓冲区
      dataBuffer += data;
      
      // 尝试解析完整的JSON消息
      let startIdx = 0;
      let endIdx = -1;
      
      // 查找可能的JSON对象边界
      while ((endIdx = findJsonEnd(dataBuffer, startIdx)) !== -1) {
        const jsonStr = dataBuffer.substring(startIdx, endIdx + 1);
        
        try {
          const message = JSON.parse(jsonStr);
          
          // 处理解析成功的消息
          handleMessage(message);
          
          // 移动到下一个潜在的JSON开始位置
          startIdx = endIdx + 1;
        } catch (parseErr) {
          // 当前字符串不是完整的JSON，可能需要更多数据
          break;
        }
      }
      
      // 移除已处理的数据
      if (startIdx > 0) {
        dataBuffer = dataBuffer.substring(startIdx);
      }
    } catch (err) {
      console.error('处理接收数据时出错:', err);
    }
  });
  
  /**
   * 处理接收到的消息
   * @param {Object} message - 解析后的消息对象
   */
  function handleMessage(message) {
    switch (message.type) {
      case 'welcome':
        console.log(`收到欢迎消息: ${message.message} (服务器ID: ${message.serverId})`);
        break;
      case 'register_ack':
        console.log(`应用注册${message.success ? '成功' : '失败'}`);
        break;
      case 'hotkey':
        handleHotKey(message.data);
        break;
      case 'remove_hotkey':
        handleRemoveHotKey(message.data);
        break;
      case 'key_event_ack':
        console.log(`键事件已确认接收: ${message.key}`);
        break;
      default:
        console.log('收到未知类型消息:', message);
    }
    } catch (err) {
      console.error('解析消息失败:', err, data);
    }
  });
  
  // 错误事件
  client.on('error', (err) => {
    console.error('连接错误:', err);
  });
  
  // 关闭事件
  client.on('close', () => {
    console.log('连接已关闭，5秒后重新连接');
    setTimeout(connectToHotKeyServer, 5000);
  });
  
  return client;
}

/**
 * 注册应用
 * @param {net.Socket} client - 客户端socket
 * @param {string} appName - 应用名称
 */
function registerApp(client, appName) {
  console.log(`注册应用: ${appName}`);
  
  const message = {
    type: 'register',
    appName
  };
  
  client.write(JSON.stringify(message));
}

/**
 * 处理热键
 * @param {Object} hotKeyModel - 热键模型
 */
function handleHotKey(hotKeyModel) {
  console.log(`\n[收到热键] ${hotKeyModel.appName}:${hotKeyModel.keyType}:${hotKeyModel.key}`);
  console.log('热键详情:', JSON.stringify(hotKeyModel, null, 2));
  
  // 在实际应用中，这里可以将热键缓存到本地
  console.log('将热键缓存到本地...');
}

/**
 * 处理热键删除
 * @param {Object} hotKeyModel - 热键模型
 */
function handleRemoveHotKey(hotKeyModel) {
  console.log(`\n[删除热键] ${hotKeyModel.appName}:${hotKeyModel.keyType}:${hotKeyModel.key}`);
  console.log('热键详情:', JSON.stringify(hotKeyModel, null, 2));
  
  // 在实际应用中，这里可以从本地缓存中删除热键
  console.log('从本地缓存中删除热键...');
}

/**
 * 模拟发送键事件
 * @param {net.Socket} client - 客户端socket
 */
function simulateKeyEvents(client) {
  // 使用多个键以增加测试覆盖范围
  const keys = ['user1', 'product2', 'order3'];
  
  // 计数器，用于跟踪每个键的累计计数
  const counters = {};
  keys.forEach(key => counters[key] = 0);
  
  console.log('\n开始模拟发送键事件...');
  
  // 每200毫秒发送一个键事件
  const interval = setInterval(() => {
    // 随机选择一个键
    const key = keys[Math.floor(Math.random() * keys.length)];
    
    // 增加计数（更大的数字，更容易触发阈值）
    const count = Math.floor(Math.random() * 3) + 3; // 随机3-5个计数
    counters[key] += count;
    
    // 创建键事件 - 注意：使用hash类型以匹配app2的规则配置
    const keyEvent = {
      type: 'key_event',
      appName: APP_NAME,
      keyType: 'hash',  // 修改为hash类型，匹配app2的配置
      key: key,
      count: count
    };
    
    console.log(`发送键事件: ${key}，计数: ${count}，累计: ${counters[key]}`);
    client.write(JSON.stringify(keyEvent));
    
    // 每10次发送一个大计数事件，确保触发热键
    if (counters[key] % 10 === 0) {
      const burstEvent = {
        type: 'key_event',
        appName: APP_NAME,
        keyType: 'hash',
        key: key,
        count: 15  // 发送一个较大的计数，确保触发热键
      };
      console.log(`发送突发键事件: ${key}，计数: 15，累计: ${counters[key] + 15}`);
      setTimeout(() => client.write(JSON.stringify(burstEvent)), 100);
      counters[key] += 15;
    }
  }, 200);
  
  // 15秒后停止发送
  setTimeout(() => {
    clearInterval(interval);
    console.log('\n模拟发送键事件结束');
  }, 15000);
}

/**
 * 启动测试客户端
 */
function startClient() {
  console.log('启动热键测试客户端');
  
  // 连接到热键服务器
  const client = connectToHotKeyServer();
  
  // 处理命令行参数
  const args = process.argv.slice(2);
  const simulate = args.includes('--simulate') || args.includes('-s');
  
  if (simulate) {
    // 等待连接和注册成功后，开始模拟发送键事件
    setTimeout(() => simulateKeyEvents(client), 2000);
  }
  
  // 优雅退出
  process.on('SIGINT', () => {
    console.log('客户端关闭中...');
    client.end();
    process.exit(0);
  });
}

// 启动客户端
startClient();
